/* function to draw heatmap of final statistics and other linked info */
var draw_heatmap = function(json, index, anno, ctrls, div, screentype) {
	function sortNumber(a,b) {
		return a - b;
	} 

	hit_threshold = 0.05
	/* json is the data object */   
	h = 1450;
	w = 200;

	pad = {
		left: 70,
		top: 70,
		right: 20,
		bottom: 70
		};
	totalh = h + pad.top + pad.bottom;
	totalw = (w + pad.left + pad.right);

	/* Context panel */

	var contxt_div=d3.select(div).append("div")   
		.attr("class", "context_div")               
		.style("display", "none");

	var btn = $('<button id="tcga_btn"></button>');
	$('.context_div').append(btn);

	var ach_tbl_div=contxt_div.append("div")   
		.attr("class", "achilles_tbl")              
		;

	var gscore_div=contxt_div.append("div")   
		.attr("class", "achilles_gscore")               
		.style("overflow", "auto")
		;

	var tcga_div=contxt_div.append("div")   
		.attr("class", "tcga_expr")               
		.style("display", "none")
		.style("overflow", "auto")
		;


	svg = d3.select(div).append("svg").attr("height", totalh).attr("width", totalw*3);


	//################## drawing axes #################### 
	val_domain = Object.keys(json[0]).filter(function(d){return d != 'RankProd' && d != 'PFP' && d != 'P-val' && d != 'plateid' && d != 'ind'})
		rp_domain = ['RankProd', 'PFP', 'P-val']

		var x = d3.scale.ordinal()
		.domain(val_domain)
		.rangeBands([0, w]);
	var xAxis = d3.svg.axis()
		.scale(x)
		.orient("top").tickSize(h);


	anno = anno.map(function(d, i){
		if(typeof d != 'string'){
			return index[i]
		}else{
			return d
		}
	})    
	if(anno.length>0){
		y_ind=anno
	}else{
		y_ind=index 
	}
	var y = d3.scale.ordinal()
		.domain(y_ind)
		.rangeBands([0, h]);
	var yAxis = d3.svg.axis()
		.scale(y)
		.orient("left").tickSize(-w);


	corrplot = svg.append("g").attr("id", "corrplot")
		.attr("transform", "translate(" + pad.left + "," + pad.top + ")");

	corrplot.append("g")
		.attr("class", "x axis")
		.attr("transform", "translate(0," + h + ")")
		.call(xAxis);
	corrplot.append("g")
		.attr("class", "y axis")
		.call(yAxis);

	rp_table = svg.append("g").attr("id", "rp_table")
		.attr("transform", "translate(" + totalw + "," + pad.top + ")");

	//################## adding data #################### 
	//
	data_array = [];
	data = [];
	for (i in json) {
		for (j in json[i]) {
			if (j != 'RankProd' && j != 'PFP' && j != 'P-val' && j != 'plateid' && j != 'ind'){
				data_array.push(json[i][j])
					data.push({
						ind: i,
						col: j,
						value: json[i][j],
					});
			}
		}
	}
	allhits = json.filter(function(d){if(d.PFP < hit_threshold)return d})

		var ctrl_cmap={'pos':'red',
			'nt':'black',
			'untreated':'green',
			'nontarg':'gold',
			'other':'yellow'
		}



	//################## draw heatmap #################### 
	corXscale = d3.scale.ordinal().domain(val_domain).rangeBands([0, w]);
	corYscale = d3.scale.ordinal().domain(index).rangeBands([0, h]);
	if(Math.min.apply(null, data_array)<0){
		corZscale = d3.scale.linear().domain([Math.min.apply(null, data_array), 0, Math.max.apply(null, data_array)]).range(["darkslateblue", "white", "crimson"]);
	}
	else{corZscale = d3.scale.linear().domain([Math.min.apply(null, data_array), Math.max.apply(null, data_array)]).range(["darkslateblue", "crimson"]);
	}



	/* Tooltip */
	var tooltip_div=d3.select("body").append("div")   
		.attr("class", "tooltip")               
		.style("opacity", 0);



	/* draw delta z heatmap */
	cells = corrplot.selectAll("empty").data(data).enter().append("rect").attr("class", "cell"
			).attr("x", function(d) {
				return corXscale(d.col);
			}).attr("y", function(d) {
				return corYscale(d.ind);
			}).attr("width", corXscale.rangeBand())
	.attr("height", corYscale.rangeBand())
		.attr("fill", function(d) {
			return corZscale(d.value);
		}).attr("cursor", "pointer")
	.attr("stroke", function(d){
		if (d.ctrl!=null)
	{ 
		return ctrl_cmap[d.ctrl.type];}
		else{return "white";}})
		.attr("stroke-width", 3)
		.on("mouseover", function(d) {
			tooltip_div.transition().duration(500)      
			.style("opacity", .7);

		if (anno.length>0) {
			html="Value:"  + d.value + " Annotation: " 
			+"<br/>" + anno[d.ind]
		}  
		else {html="Value:"  + d.value + " Annotation: ?" }

		tooltip_div.html(html)  
			//.style("left", (d3.select(this).attr("x")) + "px")     
			.style("left", (d3.event.pageX) + "px")
			.style("top", (d3.event.pageY - 28) + "px"); 



		}).on("click", function(d){
			pl_id = json[d.ind]['plateid']
			hits = allhits.filter(function(d){if (pl_id == d['plateid']) return d;})
			hits = hits.map(function(d){return d.ind.split('-')[0]})
			para = ''
			if (hits.length>0)
		{ para = '?hit='+hits.join('&hit=')
		}

		window.open("/p/"+pl_id+para)

		})
	.on("mouseout", function() {
		tooltip_div.transition()        
		.duration(1000)      
		.style("opacity", 0); 
	})
	;


	rp_Xscale = d3.scale.ordinal().domain(rp_domain).rangeBands([0, w*1.5]);

	var rp_xAxis = d3.svg.axis()
		.scale(rp_Xscale)
		.orient("top").tickSize(h);

	rp_table.append("g")
		.attr("class", "x axis")
		.attr("transform", "translate(0," + h + ")")
		.call(rp_xAxis);

	function draw_rp_tbl(stat, fmt, color){
		rp_table.selectAll("empty").data(json).enter().append("rect").attr("class", "cell"
				).attr("x", function(d) {
					return rp_Xscale(stat);
				}).attr("y", function(d) {
					return corYscale(d.ind);
				}).attr("width", rp_Xscale.rangeBand())
		.attr("height", corYscale.rangeBand())
			.on("click", get_achilles)
			.attr("stroke-width", 3)
			.attr("stroke", "white")
			.attr('fill', color);

		rp_table.selectAll("empty").data(json).enter().append("text")
			.attr('x', function(d) {
				return rp_Xscale(stat);
			}).attr("y", function(d) {
				return corYscale(d.ind) + corYscale.rangeBand()*0.8;
			}).text(function(d) {
				return fmt(d[stat]);
			}).style("font-size","0.7em")
		.on("click", get_achilles)
			.attr('fill', 'white')
			.attr("transform", "translate("+ rp_Xscale.rangeBand()*0.3 +", 0)")
			;


	}

	// actions when you click a gene for context
	function get_achilles(d, i){

		var gene = anno[i];

		$('.achilles_tbl').fadeOut(300)
			$('.achilles_tbl').fadeIn(300)

			$.get( "/getcontxt/", { g_sym:gene,  act:'achilles', })
			.done(function(res) {
				ach_tbl_div.html(res.tbl);
				$('#tcga_btn').val(gene).html('Show '+gene+' expression in TCGA cancer types')

				if(res.gs.length>0){
					draw_gscore(res.gs, '.achilles_gscore', 2500, 300) 

					d3.select('.achilles_gscore').append("text").text("Gene level essentiality across cell lines")
					.attr("x", pad.left*2).attr("y", heatmap_h*1.2)
					.attr("dominant-baseline", "middle")
					.attr("text-anchor", "middle");
				}else{
					d3.select('.achilles_gscore svg').remove();
				}

			});


		$(".context_div").show();

	}

	// Draw heatmap for the gscore     
	function draw_gscore(gs, div_name, div_w, div_h){
		var heatmap_h=80
		var data_array=gs.map(function(d){return d.value})

		d3.select(div_name+' svg').remove();

		gscore_svg = d3.select(div_name).append("svg")
			.attr("height", div_h+pad.bottom)
			.attr("width", div_w+pad.left)
			.append("g")
			.attr("transform", "translate(" + pad.left + ", "+(div_h-heatmap_h)+")");


		// hack to get gs_ids if more than 1 gene score are found
		g_ids=[]
			for(i=0;i<gs.length;i++){
				id=gs[i].gs_id
					if(g_ids.length==0){
						g_ids.push(id)
					}else{
						if($.inArray(id, g_ids)<0){
							g_ids.push(id)
						}
					}
			}

		sample_names = gs.map(function(d){return d.sample})

		gs_Xscale = d3.scale.ordinal().domain(sample_names).rangeBands([0, div_w]);
		gs_Yscale = d3.scale.ordinal().domain(g_ids).rangeBands([0, heatmap_h]);	

		if(Math.min.apply(null, data_array)<0){
			gs_Zscale = d3.scale.linear().domain([Math.min.apply(null, data_array), 0, Math.max.apply(null, data_array)]).range(["blue", "white", "red"]);
		}
		else{gs_Zscale = d3.scale.linear().domain([Math.min.apply(null, data_array), Math.max.apply(null, data_array)]).range(["blue", "red"]);
		}

		var xAxis = d3.svg.axis()
			.scale(gs_Xscale)
			.orient("top")
			.tickSize(0);
		var yAxis = d3.svg.axis()
			.scale(gs_Yscale)
			.orient("left")
			.tickSize(0)
			;

		gscore_svg.append("g")
			.attr("class", "x axis")
			//.attr("transform", "translate(0, -80)")
			.call(xAxis)
			.selectAll("text")
			.attr("transform", "rotate(-90)")
			.style("text-anchor", "start");
		;


		gscore_svg.append("g")
			.attr("class", "y axis")
			.call(yAxis);


		gscore_svg.selectAll("empty").data(gs).enter().append("rect").attr("class", "cell"
				).attr("x", function(d) {
					return gs_Xscale(d.sample);
				}).attr("y", function(d) {
					return gs_Yscale(d.gs_id);
				}).attr("width", gs_Xscale.rangeBand())
		.attr("height", gs_Yscale.rangeBand())
			.attr("stroke-width", 1)
			.attr("stroke", "white")
			.attr("fill", function(d){
				return gs_Zscale(d.value);   
			}).on("mouseover", function(d) {
				tooltip_div.transition().duration(500)      
				.style("opacity", .7);

			html="Gene level score:"  + d.value 
				tooltip_div.html(html)  
				//.style("left", (d3.select(this).attr("x")) + "px")     
				.style("left", (d3.event.pageX) + "px")
				.style("top", (d3.event.pageY - 28) + "px"); 



			})
		;

		// a quick hack to make tick txt small after drawing gscore heatmap
		d3.selectAll(".tick > text").style("font-size",'0.5em')


	}
	
	// Call action to get TCGA sample expression of a gene
	$('#tcga_btn').on('click', function(){
		var gene = $(this).val();
		$.get( "/getcontxt/", { g_sym:gene,  act:'tcga', })
		.done(function(res){

			draw_gscore(res, '.tcga_expr', 400, 200) 
			$('.tcga_expr').show()
				
		});
	});

	var fmt = d3.format(".2f");
	color = function(d){
		if (d.PFP<hit_threshold) {
			return 'purple'}
		else {return '#7FDBFF'}
	}
	draw_rp_tbl('RankProd', fmt, color);

	var fmt = d3.format(".7f");
	draw_rp_tbl('PFP', fmt, color);
	draw_rp_tbl('P-val', fmt, color);




	corrplot.append("rect").attr("height", h).attr("width", w).attr("fill", "none").attr("stroke", "black").attr("stroke-width", 1).attr("pointer-events", "none");
	corrplot.append("text").text("Rank Product result").attr("id", "corrtitle").attr("x", w / 2).attr("y", -pad.top / 2).attr("dominant-baseline", "middle").attr("text-anchor", "middle");

	d3.selectAll(".tick > text").style("font-size",'0.5em')
}
